package org.bangumibuddy.service.Impl;

import com.uwetrottmann.tmdb2.Tmdb;
import com.uwetrottmann.tmdb2.entities.TvSeason;
import com.uwetrottmann.tmdb2.entities.TvShow;
import com.uwetrottmann.tmdb2.entities.TvShowResultsPage;
import com.uwetrottmann.tmdb2.services.SearchService;
import de.androidpit.colorthief.ColorThief;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.bangumibuddy.pojo.anime.AnimeSummary;
import org.bangumibuddy.service.MovieScrapingService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import retrofit2.Call;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.*;

@Slf4j
public class TmdbMoviceScrapingService implements MovieScrapingService {
    Tmdb tmdb;

    public TmdbMoviceScrapingService(@Value("${tmdb.apikey}") String apiKey) {
        tmdb = new Tmdb(apiKey);
    }

    @Override
    @SneakyThrows
    public AnimeSummary getAnimeSummary(String name, Integer season, String language) {
        List<TvShow> tvshows = GetTvShow(name, season, language);
        if (tvshows.size() == 1) {
            TvShow tvShow = tvshows.get(0);
            //find season
            for (int i = 0; i < tvShow.seasons.size(); i++) {
                if (tvShow.seasons.get(i).season_number == season) {
                    TvSeason tvSeason = tvShow.seasons.get(i);
                    AnimeSummary animeSummary = new AnimeSummary();
                    animeSummary.setName(tvShow.name);
                    animeSummary.setOriginalName(tvShow.original_name);
                    animeSummary.setSeason(tvSeason.name);
                    animeSummary.setPoster("https://image.tmdb.org/t/p/w500" + tvSeason.poster_path);
                    animeSummary.setDescription(tvShow.overview);

                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(tvSeason.air_date);
                    animeSummary.setYear(calendar.get(Calendar.YEAR));
                    animeSummary.setMonth(calendar.get(Calendar.MONTH) + 1);

                    List<String> types = new ArrayList<>();
                    for (int j = 0; j < tvShow.genres.size(); j++) {
                        types.add(tvShow.genres.get(j).name);
                    }
                    animeSummary.setType(String.join(", ", types));

                    animeSummary.setBackgroundURL("https://image.tmdb.org/t/p/original" + tvShow.backdrop_path);
                    animeSummary.setBackgroundColor(GetBackDropColor(animeSummary.getBackgroundURL()));
                    return animeSummary;
                }
            }
        }

        return null;
    }

    @Override
    public String getAnimeEnglishName(String name, Integer season) {
        return getNames(name, season, "en").get(0);
    }

    @Override
    public List<String> getAnimeZhName(String name, Integer season) {
        return getNames(name, season, "zh");
    }

    private List<String> getNames(String name, Integer season, String language) {
        TvShowResultsPage page = GetTvShowResultsPage(name, season, language);
        if (page == null) {
            return null;
        }

        List<String> names = new ArrayList<>();
        for (int i = 0; i < page.results.size(); i++) {
            names.add(page.results.get(i).name);
        }

        return names;
    }

    @SneakyThrows
    private List<TvShow> GetTvShow(String name, Integer season, String language) {
        TvShowResultsPage page = GetTvShowResultsPage(name, season, language);
        List<TvShow> result = new ArrayList<>();
        for (int i = 0; i < page.results.size(); i++) {
            Integer id = page.results.get(i).id;
            TvShow tvShow = GetTvShow(id,language);
            result.add(tvShow);
        }

        return result;
    }

    @SneakyThrows
    private TvShow GetTvShow(Integer id,String language) {
        TvShow tvShow = tmdb.tvService().tv(id, language).execute().body();

        return tvShow;
    }

    @SneakyThrows
    private TvShowResultsPage GetTvShowResultsPage(String name, Integer season, String language) {
        SearchService searchService = tmdb.searchService();
        Call<TvShowResultsPage> call = searchService.tv(name, null, language, null, false);
        TvShowResultsPage body = call.execute().body();

        return body;
    }

    @SneakyThrows
    private String GetBackDropColor(String path) {
        URL url = new URL(path);
        BufferedImage image = ImageIO.read(url);
        int[] color = ColorThief.getColor(image);
        return color[0] + "," + color[1] + "," + color[2];
    }
}
